import org.newdawn.slick.*;

/**
 * Keeps track of the current states and switches between them.
 * Input provided by the player is routed to the state with the
 * lowest int index. Network actions are routed to the GAME if
 * possible, otherwise to the LOBBY state. Will call forwardNetworkActions.
 *
 * @author dbos
 * @version 2008-04-18
 */
public class ApplicationStateManager
{
    // currently active states
    private boolean[] activeStates = new boolean[4];
	// the chat lobby state
	public static int CHAT=3;
    // the game state
    public static int GAME=2;
    // the lobby state
    public static int LOBBY=1;
    // the menu state
    public static int MENU=0;
    // containes the actual states
    private ApplicationState[] states = new ApplicationState[4];
    // the currently active state
    private ApplicationState currentState;

    /**
     * Constructor for objects of class ApplicationStateManager
     */
    public ApplicationStateManager(GameContainer cont)
    {
        this.states[0] = new MenuState(this);
        this.states[1] = new LobbyState(this, cont);
        this.states[2] = new GameSessionState(this, cont);
		this.states[3] = new ChatLobbyState(this, cont);
        this.activeStates[0] = true;
        this.activeStates[1] = false;
        this.activeStates[2] = false;
		this.activeStates[3] = false;
        this.currentState = states[0];
		getCurrentState().setMode(null);
    }

    /**
     * Forwards actions from InputManager to the current state
     *
     * @param  action   String representing an action
     */
    public void forwardInput(String action)
    {
		// ugly hack to make a global disable/enable music button
		if (action.equals("p_music")) {
			Multitris.musicEnabled = !Multitris.musicEnabled;
			if (Multitris.currentMusic.playing()) {
				Multitris.currentMusic.pause();
			} else {
				Multitris.currentMusic.resume();
				//Multitris.currentMusic.setVolume(0.3f);
			}
			/*if (currentState == states[GAME]) {
				if (Multitris.music[Multitris.MUSIC_GAME].playing()) {
					Multitris.music[Multitris.MUSIC_GAME].pause();
				} else {
					Multitris.music[Multitris.MUSIC_GAME].resume();
				}
			} else {
				if (Multitris.music[Multitris.MUSIC_MENU].playing()) {
					Multitris.music[Multitris.MUSIC_MENU].pause();
				} else {
					Multitris.music[Multitris.MUSIC_MENU].resume();
				}
			}*/
		}
		if (action.equals("p_sound")) {
			Multitris.soundEnabled = !Multitris.soundEnabled;
		}
        currentState.doInputAction(action);
        System.out.println(action);
    }

    /**
     * Set a state as active or inactive
     *
     * @param  state   the state top be set
     * @param  value   true for active
     */
    public void setStateActive(int state, boolean value)
    {
        activeStates[state] = value;
    }

    /**
     * Forwards server actions from the ClientCommunication class to current state
     *
     * @param  actions   an array of strings representing actions to perform
     */
    public void forwardNetworkAction(String[] actions)
    {
        for(int i = 0; i < actions.length; i++) {
           currentState.doInputAction(actions[i]);
        }
    }

	/**
	* Informs the ApplicationStateManager that the mouse has been moved.
	* The information is forwarded to the current state.
	*
	* @param oldx The old x coordinate.
	* @param oldy The old y coordinate.
	* @param newx The new x coordinate.
	* @param newy The new y coordinate.
	*/
	public void forwardMouseMoved(int oldx, int oldy, int newx, int newy) {
		currentState.mouseMoved(oldx, oldy, newx, newy);
	}

	/**
	* Informs the ApplicationStateManager that a mouse button has been pressed.
	* The information is forwarded to the current state.
	*
	* @param button The old mouse button pressed.
	* @param y The y coordinate.
	* @param x The x oordinate.
	*/
	public void forwardMousePressed(int button, int x, int y) {
		//if(stateMan.getCurrentState().equals(stateMan.getState(ApplicationStateManager.MENU)))
		//	((MenuState)stateMan.getCurrentState()).mousePressed(button, x, y);
		currentState.mousePressed(button, x, y);
	}

    /**
     * Change the current state
     *
     * @param  state   number representing a state (MENU=0 LOBBY=1 GAME=2)
     */
    public void switchState(int state)
    {
        currentState = states[state];
    }

    /**
     * Change the current state, forward a parameter to the current state.
     *
     * @param  state   number representing a state (MENU=0 LOBBY=1 GAME=2)
     * @param  param   a parameter to forward to the current state.
     */
    public void switchState(int state, Object parameter)
    {
        currentState = states[state];
        currentState.setMode(parameter);
    }

    /**
     * retreive the current state
     *
     * @return     the currently active state
     */
    public ApplicationState getCurrentState() {
        return currentState;
    }

    /**
     * retreive the given state
     *
     * @param state the state index
     * @return     the given state
     */
    public ApplicationState getState(int state) {
        return states[state];
    }

}